#include <iostream>
#include <string>
#include <pthread.h>
#include <unistd.h>

using namespace std;

int tickets = 1000;//共享资源

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

void *start_routine(void *args)
{
    string name = static_cast<const char *>(args);
    while(true)
    {
        pthread_mutex_lock(&mutex);
        pthread_cond_wait(&cond, &mutex);//线程先别执行什么逻辑，上来就给我去cond队列里面进行等待。为什么要有mutex，后面说

        //判断票数是否大于零的逻辑，暂时省略...
        cout << name << " -> " << tickets-- << endl;
        pthread_mutex_unlock(&mutex);
    }
}

int main()
{
    //通过条件变量控制线程的执行---
    pthread_t t[5];
    for(int i = 0; i < 5; i++)
    {
        // char name[64];//这样传给线程，有可能线程执行的时候，主线程已经又重新创建了name数组，所以线程的名字可能有问题---
        char *name = new char[64];//所以我们采用在堆上开辟数组的方式，这样新线程用数组的时候，数组不会由于主线程for循环而重复开辟和销毁

        snprintf(name, 64, "thread %d", i+1);
        pthread_create(t+i, nullptr, start_routine, name);
    }
    // pthread_create(&t1, nullptr, start_routine, (void*)"thread 1");
    // pthread_create(&t2, nullptr, start_routine, (void*)"thread 2");

    while(true)
    {
        sleep(1);//主线程来控制唤醒线程的节奏
        pthread_cond_signal(&cond);//让主线程来模拟面试官，去唤醒cond里的线程
        // pthread_cond_broadcast(&cond);

        //因为是主线程唤醒cond队列里面的线程，所以将来线程运行的时候，打印出来的语句一定会有非常强的顺序性
        cout << "main thread wake up a thread..." << endl;
    }

    // pthread_join(t1, nullptr);
    // pthread_join(t2, nullptr);

    for(auto tid : t)
    {
        pthread_join(tid, nullptr);
    }


    return 0;
}    






























